package com.king.base.service.verify.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.king.base.auth.utils.EntityUtils;
import com.king.base.msg.expection.BadRequestException;
import com.king.base.domain.verify.VerifyCode;
import com.king.base.mapper.verification.VerificationCodeMapper;
import com.king.base.service.verify.VerifyCodeService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author TianYZ
 * @date 2019-06-16
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class VerifyCodeServiceImpl extends ServiceImpl<VerificationCodeMapper, VerifyCode> implements VerifyCodeService {

    @Value("${code.expiration}")
    private Integer expiration;

    @Override
    public void validated(VerifyCode code) {
        VerifyCode verifyCode = baseMapper.findByScenesAndTypeAndValueAndStatusIsTrue(code.getScenes(), code.getType(), code.getValue());
        if (verifyCode == null || !verifyCode.getCode().equals(code.getCode())) {
            throw new BadRequestException("无效验证码");
        } else {
            verifyCode.setStatus(false);
            EntityUtils.setUpdatedInfo(verifyCode);
            baseMapper.updateById(verifyCode);
        }
    }

    /**
     * 定时任务，指定分钟后改变验证码状态
     *
     * @param verifyCode
     */
    private void timedDestruction(VerifyCode verifyCode) {
        //以下示例为程序调用结束继续运行
        ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
        try {
            executorService.schedule(() -> {
                verifyCode.setStatus(false);
                EntityUtils.setUpdatedInfo(verifyCode);
                baseMapper.updateById(verifyCode);
            }, expiration * 60 * 1000L, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
